iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
1
Modern Web

今晚,我想來點Blazor系列 第 15

Day 15:元件之間的溝通

  • 分享至 

  • xImage
  •  

Blazor與其他前端框架一樣,是由一個一個元件(component)所組合而成的,每個元件都有各自的用途,將這些元件拼湊起來,就成了我們的SPA應用程式,所以我們時常會遇到元件需要互相傳遞資料的情況,一種常見的組合模式是巢狀元件,也就是一個元件內還包含另一個元件。
https://ithelp.ithome.com.tw/upload/images/20200929/20130058mq9YJuCg1u.png
巢狀元件傳遞資料的方式大概如上圖

父元件傳給子元件

父元件要傳遞資料給子元件的作法,就是透過Parameter傳遞,子元件可以透過Paramter屬性取得資料。

子元件傳給父元件

子元件需要設定一個型別為EventCallback或EventCallback的Paramter屬性,這個屬性的主要用途,是讓子元件可以透過EventCallback的InvokeAsync方法,傳遞資料給父元件。而父元件這邊,則需要再新增一個callback method,來接收子元件資料並做後續處理。

接下來我們來做個Todolist來試試看吧,下圖是我們準備要做出的Todolist,外層的父元件顯示所有的Todo Item,並且可以新增Todo Item,而每一個子元件需要顯示單獨的Item和Delete按鈕,按下Delete後會傳遞Item index給父元件,父元件透過callback method接收item index後,進行刪除item動作。https://ithelp.ithome.com.tw/upload/images/20200929/20130058dpUBALTdz3.jpg

我們先來看父元件的程式

@page "/Todo"

<div>
    <table class="table table-hover">
        <tr>
            <th>待辦事項</th>
            <th>刪除</th>
        </tr>
        @for (int i = 0; i < TodoList.Count; i++)
        {
            <Todo ItemName="@TodoList[i]" ItemIndex="@i" DeleteItem="@DeleteCallback" />
        }
    </table>
</div>

<div>
    <label>New Todo:</label> <input type="text" @bind="newTodoItem" /> <button class="btn btn-primary" @onclick="Add">Add</button>
</div>
<br />

@code{
    private string newTodoItem;
    private List<string> TodoList;

    protected override void OnInitialized()
    {
        TodoList = new List<string>()
        {
            "Buy Milk",
            "Buy Apple"
        };
    }

    void Add()
    {
        if (!string.IsNullOrEmpty(newTodoItem))
        {
            TodoList.Add(newTodoItem);
            newTodoItem = "";
        }
    }

    void DeleteCallback(int index)
    {       
        TodoList.RemoveAt(index);
    }

}
  • 在OnInitialized初始化一個TodoList,型別是List,並先設定2筆Todo Item。
  • Html部分,使用Razor for迴圈,將每Item Name和index傳給Todo這個子元件,注意到Todo中的DeleteItem="@DeleteCallback",這個@DeleteCallback就是父元件接收子元件item index的callback method。在@code區塊的DeleteCallback method會將該Item從Todolist刪除。
  • 在html的table下方,多加一個input和新增按鈕以及Add方法,來新增Todo Item。

再來我們看子元件Todo.razor的部分。

<tr>
    <td>@ItemName </td>
    <td><button class="btn btn-danger btn-sm" @onclick="Delete">delete</button></td>
</tr>

@code {
    [Parameter]
    public string ItemName { get; set; }

    [Parameter]
    public int ItemIndex { get; set; }

    [Parameter]
    public EventCallback<int> DeleteItem { get; set; }

		void Delete()
    {
        DeleteItem.InvokeAsync(ItemIndex);
    }
}
  • 宣告ItemName和ItemIndex這2個Parameter屬性,接收父元件傳來的Item Name和index。
  • 宣告ItemName和ItemIndex這2個Parameter屬性,接收父元件傳來的Item Name和index。
  • 點擊刪除按鈕,執行@Code區塊的Delete方法,這邊使用DeleteItem.InvokeAsync(),並傳入ItemIndex
  • @onclick="Delete"也可以寫成下面這樣,就不用再另外寫一個 Delete方法。
@onclick=(() ⇒ DeleteItem.InvokeAsync(ItemIndex))

看看我們的TodoList吧


上一篇
Day 14:Arbitrary Parameter 任意參數
下一篇
Day 16:Cascading Paramater
系列文
今晚,我想來點Blazor30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言